package douaPahare.algotihm;
import java.util.ArrayList;
import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;

import douaPahare.container.Actiune;
import douaPahare.container.Arbore;
import douaPahare.container.Stare;
import douaPahare.operator.Operator;

public class BSF extends Algorithm {
	
	private ArrayList<Stare> listaStariTrecute;
	private Stack<Actiune> path;
	private Stare stareSolution;
	private int index;
	
	public BSF() {
		a = Arbore.getInstance();
		a.resetRadacina();
		listaStariTrecute = new ArrayList<Stare>();
		path = new Stack<Actiune>();
		solution = false;
		index = 0;
		stareSolution = null;
	}
	
	public void solve() {
		System.out.println("---------> Rezolvare folosind algoritmul BSF:");
		ArrayList<Stare> listaStariAux = new ArrayList<Stare>();
		listaStariAux.add(a.getRadacina());
		while(!isSolution()) {
			for(Stare s : listaStariAux) {
				if(!search(s) && !isSolution()) {
					s.setListaStari(expand(s));
					listaStariTrecute.add(s);
				}
			}
			listaStariAux.clear();
			for(int i = index;i < listaStariTrecute.size();i++) {
				for(Stare s : listaStariTrecute.get(i).getListaStari()) {
					listaStariAux.add(s);
				}
			}
			index = listaStariTrecute.size();
		} 
		System.out.println("Solution found!");
	}
	
	public ArrayList<Stare> expand(Stare st) {
		System.out.println("Stare : (" + st.getX() + "," + st.getY() + ") expandata : ");
		Stare aux;
		Actiune ac;
		ArrayList<Stare> ls = new ArrayList<Stare>();
		for(Operator op : listaOperatori) {
			if(op.evaluare(st)) {
				aux = op.actiune2(st);
				ac = new Actiune(st,op);
				aux.setParent(ac);
				ls.add(aux);
				aux.printStare();
				if(aux.getX() == 0 && aux.getY() == 2) {
					solution = true;
					stareSolution = (Stare)aux.clone();
					break;
				}
			}
		}
		return ls;
	}
	
	public boolean search(Stare st) {
		boolean b = false;
		for(Stare s : listaStariTrecute) {
			if((s.getX() == st.getX()) && (s.getY() == st.getY())) {
				b = true;
				break;
			}
		}
		return b;
	}
	
	public Stack<Actiune> findPath() {
		stareSolution.printStare();
		Stare aux = stareSolution;
		while(aux.getParent() != null) {
			path.push(aux.getParent());
			aux = aux.getParent().getStare();
		}
		return path;
	}
}
 